#ifndef __DRV_USART_H__
#define __DRV_USART_H__

#include "Includes.h"
#include "stdio.h"
#include <stdint.h>
#include <stm32f10x.h>

enum way{
    INT_WAY=0,
    DMA_WAY,
    BLOCK_WAY,
    MAX_WAY
};
    
typedef struct {
  USART_TypeDef *usart_periph;
  enum way work_way;
  DMA_Channel_TypeDef *dma_rxchannel;
  DMA_Channel_TypeDef *dma_txchannel;
  uint8_t *tx_buf;
  uint16_t tx_buf_size;
  uint16_t tx_rd;
  uint16_t tx_wr;
  uint8_t *rx_buf;
  uint16_t rx_buf_size;
  uint16_t rx_rd;
  uint16_t rx_wr;
  SemaphoreHandle_t rx_mux;
  uint8_t *dma_tx_buf;
  uint16_t dma_tx_buf_size;
  uint8_t *dma_rx_buf;
  uint16_t dma_rx_buf_size;
  void (*config)(void);
  void (*deconfig)(void);
  void (*dma_rxconfig)(void);
  void (*dma_txconfig)(void);  
  void (*dma_deconfig)(void);  
} usart_context_t;

//API: function is called by other module
extern usart_context_t usart1_context;//4g:ec800
extern usart_context_t usart2_context;
extern usart_context_t usart3_context;//meter:ht7107
extern usart_context_t usart4_context;//debug


void usart_config_init(usart_context_t *pusart_context, uint32_t brate,uint32_t dbits,uint32_t cparity);
void usart_config_mux_init(usart_context_t *pusart_context);
void usart_config_deinit(usart_context_t *pusart_context);
int usart_receive_data(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait);
int usart_read_bytes(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait);
int uart_read_bytes(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait);
int usart_send_data(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count);
int usart_write_bytes(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count);
int uart_write_bytes(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count);
void usart_printf(usart_context_t *pusart_context, char *arg, ...);
void u_tm_log(char *arg, ...);
void u_log(char *arg, ...);
void DBUG_PRINTF(char *arg, ...);
int rprintf(char *msg, ...);

#endif
